/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sheep.JUNG.utils;


import java.awt.Dimension;
import java.awt.ItemSelectable;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.EventListenerList;
import javax.swing.plaf.basic.BasicIconFactory;

import edu.uci.ics.jung.visualization.SettableVertexLocationFunction;
import edu.uci.ics.jung.visualization.control.AnimatedPickingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.GraphMousePlugin;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.control.PluggableGraphMouse;
import edu.uci.ics.jung.visualization.control.RotatingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.ScalingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.ShearingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.TranslatingGraphMousePlugin;

//////////////////////////////////////////////////////////////////////////////////////
import sheep.controller.Workspace;


/**
 * @author geek
 *
 */
public class OurModalGraphMouse extends PluggableGraphMouse 
    implements ModalGraphMouse, ItemSelectable {
    
	//////////////////////////////////////////////////////////////////////////////////////

	
    /**
     * 
     */
    protected float in;
    protected float out;
    protected ItemListener modeListener;
    protected JComboBox modeBox;
    protected JMenu modeMenu;
    protected Mode mode;
    protected EventListenerList listenerList = new EventListenerList();
    protected GraphMousePlugin pickingPlugin;
    protected GraphMousePlugin translatingPlugin;
    protected GraphMousePlugin animatedPickingPlugin;
    protected GraphMousePlugin scalingPlugin;
    protected GraphMousePlugin rotatingPlugin;
    protected GraphMousePlugin shearingPlugin;
    protected GraphMousePlugin editingPlugin;   
    Workspace workSpace;
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @param projet
     * @param pref
     */
    public OurModalGraphMouse(Workspace workSpace) {
        this(1.1f, 1/1.1f, workSpace);
        
        
    }
    
	//////////////////////////////////////////////////////////////////////////////////////
  
    /**
     * @param in
     * @param out
     * @param projet
     * @param pref
     */
    public OurModalGraphMouse(float in, float out,Workspace workSpace) {
    	this.workSpace = workSpace;
        this.in = in;
        this.out = out;
        loadPlugins();
    }
 
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * 
     */
    protected void loadPlugins() {
        pickingPlugin = new OurPickingGraphMousePlugin(workSpace);
        animatedPickingPlugin = new AnimatedPickingGraphMousePlugin();
        translatingPlugin = new TranslatingGraphMousePlugin(InputEvent.BUTTON1_MASK);
        scalingPlugin = new ScalingGraphMousePlugin(new CrossoverScalingControl(), 0, in, out);
        rotatingPlugin = new RotatingGraphMousePlugin();
        shearingPlugin = new ShearingGraphMousePlugin();
        editingPlugin = new EditingGraphMousePlugin(workSpace);
        
        add(scalingPlugin);
        setMode(Mode.EDITING);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @param vertexLocations
     */
    public void setVertexLocations(SettableVertexLocationFunction vertexLocations) {
        ((EditingGraphMousePlugin)editingPlugin).setVertexLocations(vertexLocations);
    }

	//////////////////////////////////////////////////////////////////////////////////////

    /* (non-Javadoc)
     * @see edu.uci.ics.jung.visualization.control.ModalGraphMouse#setMode(edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode)
     */
    public void setMode(Mode mode) {
        if(this.mode != mode) {
            fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
                    this.mode, ItemEvent.DESELECTED));
            this.mode = mode;
            if(mode == Mode.TRANSFORMING) {
                setTransformingMode();
            } else if(mode == Mode.PICKING) {
                setPickingMode();
            } else if(mode == Mode.EDITING) {
                setEditingMode();
            }
            if(modeBox != null) {
                modeBox.setSelectedItem(mode);
            }
            fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, mode, ItemEvent.SELECTED));
        }
    }

	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * 
     */
    protected void setPickingMode() {
        remove(translatingPlugin);
        remove(rotatingPlugin);
        remove(shearingPlugin);
        remove(editingPlugin);
        add(pickingPlugin);
        add(animatedPickingPlugin);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * 
     */
    protected void setTransformingMode() {
        remove(pickingPlugin);
        remove(animatedPickingPlugin);
        remove(editingPlugin);
        add(translatingPlugin);
        add(rotatingPlugin);
        add(shearingPlugin);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * 
     */
    protected void setEditingMode() {
        remove(pickingPlugin);
        remove(animatedPickingPlugin);
        remove(translatingPlugin);
        remove(rotatingPlugin);
        remove(shearingPlugin);
        add(editingPlugin);
   }

	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @param zoomAtMouse
     */
    public void setZoomAtMouse(boolean zoomAtMouse) {
        ((ScalingGraphMousePlugin) scalingPlugin).setZoomAtMouse(zoomAtMouse);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @author geek
     *
     */
    class ModeListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            setMode((Mode) e.getItem());
        }
    }
	//////////////////////////////////////////////////////////////////////////////////////

    /* (non-Javadoc)
     * @see edu.uci.ics.jung.visualization.control.ModalGraphMouse#getModeListener()
     */
    public ItemListener getModeListener() {
		if (modeListener == null) {
			modeListener = new ModeListener();
		}
		return modeListener;
	}
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @return
     */
    public JComboBox getModeComboBox() {
        if(modeBox == null) {
            modeBox = new JComboBox(new Mode[]{Mode.TRANSFORMING, Mode.PICKING, Mode.EDITING});
            modeBox.addItemListener(getModeListener());
        }
        modeBox.setSelectedItem(mode);
        return modeBox;
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @return
     */
    public JMenu getModeMenu() {
        if(modeMenu == null) {
            modeMenu = new JMenu();// {
            Icon icon = BasicIconFactory.getMenuArrowIcon();
            modeMenu.setIcon(BasicIconFactory.getMenuArrowIcon());
            modeMenu.setPreferredSize(new Dimension(icon.getIconWidth()+10, 
            		icon.getIconHeight()+10));

            final JRadioButtonMenuItem transformingButton = 
                new JRadioButtonMenuItem(Mode.TRANSFORMING.toString());
            transformingButton.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        setMode(Mode.TRANSFORMING);
                    }
                }});
            
            final JRadioButtonMenuItem pickingButton =
                new JRadioButtonMenuItem(Mode.PICKING.toString());
            pickingButton.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        setMode(Mode.PICKING);
                    }
                }});
 
            final JRadioButtonMenuItem editingButton =
                new JRadioButtonMenuItem(Mode.EDITING.toString());
            editingButton.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        setMode(Mode.EDITING);
                    }
                }});

            ButtonGroup radio = new ButtonGroup();
            radio.add(transformingButton);
            radio.add(pickingButton);
            radio.add(editingButton);
            transformingButton.setSelected(true);
            modeMenu.add(transformingButton);
            modeMenu.add(pickingButton);
            modeMenu.add(editingButton);
            modeMenu.setToolTipText("Menu for setting Mouse Mode");
            addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if(e.getStateChange() == ItemEvent.SELECTED) {
						if(e.getItem() == Mode.TRANSFORMING) {
							transformingButton.setSelected(true);
						} else if(e.getItem() == Mode.PICKING) {
							pickingButton.setSelected(true);
						} else if(e.getItem() == Mode.EDITING) {
						    editingButton.setSelected(true);
                        }
					}
				}});
        }
        return modeMenu;
    }
    
	//////////////////////////////////////////////////////////////////////////////////////


    /* (non-Javadoc)
     * @see java.awt.ItemSelectable#addItemListener(java.awt.event.ItemListener)
     */
    public void addItemListener(ItemListener aListener) {
        listenerList.add(ItemListener.class,aListener);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /* (non-Javadoc)
     * @see java.awt.ItemSelectable#removeItemListener(java.awt.event.ItemListener)
     */
    public void removeItemListener(ItemListener aListener) {
        listenerList.remove(ItemListener.class,aListener);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////


    /**
     * @return
     */
    public ItemListener[] getItemListeners() {
        return (ItemListener[])listenerList.getListeners(ItemListener.class);
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

    /* (non-Javadoc)
     * @see java.awt.ItemSelectable#getSelectedObjects()
     */
    public Object[] getSelectedObjects() {
        if ( mode == null )
            return new Object[0];
        else {
            Object result[] = new Object[1];
            result[0] = mode;
            return result;
        }
    }
	//////////////////////////////////////////////////////////////////////////////////////

    /**
     * @param e
     */
    protected void fireItemStateChanged(ItemEvent e) {
        Object[] listeners = listenerList.getListenerList();
        for ( int i = listeners.length-2; i>=0; i-=2 ) {
            if ( listeners[i]==ItemListener.class ) {
                ((ItemListener)listeners[i+1]).itemStateChanged(e);
            }
        }
    }
    
	//////////////////////////////////////////////////////////////////////////////////////

}

//////////////////////////////////////////////////////////////////////////////////////